package net.mengkai.activiti7.deployer.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cmtech.workflow.server.domain.SysGroup;
import com.cmtech.workflow.server.domain.SysRole;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

public class UserInfoAuthenticationFilter extends BasicAuthenticationFilter {

    public UserInfoAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        String encodedStr = request.getHeader("userinfo");
        if (encodedStr == null) {
            chain.doFilter(request, response);
            return;
        }
        String userInfoStr = new String(Base64.getDecoder().decode(encodedStr), "utf-8");
        JSONObject userInfo = JSON.parseObject(userInfoStr);
        if (userInfo == null) {
            badToken(response);
            return;
        }

        JSONArray roles = userInfo.getJSONArray("roles");
        List authorities = new ArrayList();
        for (int i = 0; i < roles.size(); i++) {
            JSONObject role = roles.getJSONObject(i);
            authorities.add(new SysRole(role.getString("id"),
                    role.getString("name"),
                    false,
                    false));
            authorities.add(new SysGroup(role.getString("name")));
        }

        UserInfoAuthenticationToken authResult = new UserInfoAuthenticationToken(authorities, userInfo);
        SecurityContextHolder.getContext().setAuthentication(authResult);
        chain.doFilter(request, response);
    }

    private void badToken(HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter out = response.getWriter();
        Map resultMap = new HashMap();
        resultMap.put("code", HttpServletResponse.SC_UNAUTHORIZED);
        resultMap.put("msg", "user info invalid");
        out.write(new ObjectMapper().writeValueAsString(resultMap));
        out.flush();
        out.close();
    }

}
